﻿Imports System.Windows.Forms

Namespace Dialogs

    Public Class dlgWSFObjectDetail
        'Inherits from the dlgDefault in the dlgWSFObjectDetail.Designer.vb code.

#Region "**Local Variables**"
        Private l_HashTable As New Dictionary(Of String, Object)
        Private l_ObjectToDisplay As Object
        Private l_WSFObject As dbiWSF.FrameworkObjects.objWSFObjects
        Private l_WSFBusinessRules As dbiWSF.BusinessRulesAndSupport.BusinessRuleObjects
        Private l_UseBusinessRules As Boolean
#End Region

#Region "**Public Properties**"
        ''' <summary>
        ''' The dbiWSF Object to Display
        ''' </summary>
        <System.ComponentModel.Category("dbiWSF Objects"), _
        System.ComponentModel.Description("The dbiWSF Object to Display")> _
        Public Property ObjectToDisplay() As Object
            Get
                Return l_ObjectToDisplay
            End Get
            Set(ByVal value As Object)
                l_ObjectToDisplay = value
            End Set
        End Property

        ''' <summary>
        ''' The main dbiWSFObjects attached to the project.
        ''' </summary>
        <System.ComponentModel.Category("dbiWSF Objects"), _
        System.ComponentModel.Description("The main dbiWSFObjects attached to the project.")> _
        Public Property WSFObject() As dbiWSF.FrameworkObjects.objWSFObjects
            Get
                Return l_WSFObject
            End Get
            Set(ByVal value As dbiWSF.FrameworkObjects.objWSFObjects)
                l_WSFObject = value
            End Set
        End Property

        ''' <summary>
        ''' The main business rules attached to the project.
        ''' </summary>
        <System.ComponentModel.Category("dbiWSF Business Rules"), _
        System.ComponentModel.Description("The main business rules attached to the project.")> _
        Public Property WSFBusinessRules() As dbiWSF.BusinessRulesAndSupport.BusinessRuleObjects
            Get
                Return l_WSFBusinessRules
            End Get
            Set(ByVal value As dbiWSF.BusinessRulesAndSupport.BusinessRuleObjects)
                l_WSFBusinessRules = value
            End Set
        End Property

        ''' <summary>
        ''' A boolean value determining if the business rules should be applied.
        ''' </summary>
        <System.ComponentModel.Category("dbiWSF Business Rules"), _
        System.ComponentModel.Description("A boolean value determining if the business rules should be applied.")> _
        Public Property UseBusinessRules() As Boolean
            Get
                Return l_UseBusinessRules
            End Get
            Set(ByVal value As Boolean)
                l_UseBusinessRules = value
            End Set
        End Property
#End Region

#Region "**Dialog Control Event Methods**"

        Private Sub OK_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OK_Button.Click

            Try
                If Me.UseBusinessRules = True Then
                    'Check for business rules, if true, then we cache all the properties
                    'so we can undo them if the business rules fail.
                    CacheProperties()
                End If
            Catch ex As Exception
                Throw New Exception("Error caching properties") '<Generic Error> Modify as needed
            End Try

            Try

                'Map the control information back to the properties of the object.
                For Each curControl In Me.DbiWSFObjectDetailMain.Controls
                    If curControl.Tag IsNot Nothing Then
                        Dim curVal As Object = GetValue(curControl)
                        If curVal IsNot Nothing Then
                            Try
                                Dim PropInfo As System.Reflection.PropertyInfo
                                PropInfo = Me.ObjectToDisplay.GetType.GetProperty(curControl.Tag.LabelString)
                                If Not PropInfo Is Nothing Then
                                    PropInfo.SetValue(Me.ObjectToDisplay, curVal, Nothing)
                                End If
                            Catch ex As Exception
                                'Issue with property, may not exist or be an automation issue.
                                'This is intentionally unhandled as there are certain properties that
                                'won't map to the controls (collections etc.)
                            End Try
                        End If
                    End If
                Next

                If Me.UseBusinessRules Then
                    'Validate the business rules.
                    Dim AllowChange As Boolean = False
                    Dim brDialog As New dbiWSF.Dialogs.dlgBusinessRule(WSFBusinessRules)
                    brDialog.StartProcessSynch(ObjectToDisplay, BusinessRulesAndSupport.BusinessRuleObjects.RequestAction.Change)
                    AllowChange = brDialog.Allow
                    brDialog.Dispose()

                    'If the change is allowed update the data else, reset the data from the cache.
                    If AllowChange Then
                        UpdateData()
                    Else
                        ResetProperties()
                    End If
                Else 'The business rules aren't applied update the data.
                    UpdateData()
                End If


            Catch ex As Exception
                Throw New Exception("Error Updating Form Data", ex) '<Generic Error>
            End Try

            Me.DialogResult = System.Windows.Forms.DialogResult.OK
            Me.Close()
        End Sub

        Private Sub Cancel_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Cancel_Button.Click
            'Do not post any changes, set the dialog result and close the form.
            Me.DialogResult = System.Windows.Forms.DialogResult.Cancel
            Me.Close()
        End Sub

        Private Sub dlgWSFObjectDetail_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
            'Set combo box text values when the form is shown, this is to work
            'around an issue with the comboboxes when added at runtime instead
            'of design time.
            For Each curCtrl As Windows.Forms.Control In Me.DbiWSFObjectDetailMain.Controls
                If curCtrl.GetType.ToString = GetType(Windows.Forms.ComboBox).ToString Then
                    Dim curCombo As Windows.Forms.ComboBox = curCtrl
                    curCombo.SelectedItem = curCtrl.Tag.ControlValue
                End If
            Next
        End Sub
#End Region

#Region "**dlgWSFObjectDetail Methods**"
        ''' <summary>Overloaded: Displays the dialog with any dbiWSF object and the main dbiWSFObjects for the project.</summary>
        Public Sub ShowWithObject(ByRef ObjectToDisplay As Object, ByRef wsfObject As dbiWSF.FrameworkObjects.objWSFObjects)
            Me.ObjectToDisplay = ObjectToDisplay
            Me.WSFObject = wsfObject
            Me.UseBusinessRules = False
            DisplayDialog()
        End Sub
        ''' <summary>Overloaded: Displays the dialog with any dbiWSF object and the main dbiWSFObjects for the project,
        ''' and a main business rules object.</summary>
        Public Sub ShowWithObject(ByRef ObjectToDisplay As Object, ByRef wsfObject As dbiWSF.FrameworkObjects.objWSFObjects, _
                                   ByRef BusinessRules As dbiWSF.BusinessRulesAndSupport.BusinessRuleObjects)
            Me.ObjectToDisplay = ObjectToDisplay
            Me.WSFObject = wsfObject
            Me.WSFBusinessRules = BusinessRules
            Me.UseBusinessRules = True
            DisplayDialog()
        End Sub
        ''' <summary>Supporting Method: Displays the dialog from the ShowWithObject methods.</summary>
        Private Sub DisplayDialog()
            Try
                If Me.ObjectToDisplay IsNot Nothing Then
                    'Calls the dbiWSFObjectDetail.vb control DisplayObject method to parse the object properties
                    'into the control.
                    Me.DbiWSFObjectDetailMain.DisplayObject(ObjectToDisplay, WSFObject)
                    SetText()

                    Me.ShowDialog()
                End If
            Catch ex As Exception
                Throw New Exception("DisplayDialog", ex)
            End Try
        End Sub

        ''' <summary>Supporting Method: Caches the current property settings for use with
        ''' business rules and undoing changes if they fail.</summary>
        Private Sub CacheProperties()
            l_HashTable.Clear()
            Dim MainPropInfo As System.Reflection.PropertyInfo
            For Each MainPropInfo In ObjectToDisplay.GetType.GetProperties
                l_HashTable.Add(MainPropInfo.Name, MainPropInfo.GetValue(ObjectToDisplay, Nothing))
            Next
        End Sub

        ''' <summary>Supporting Method: Resets the properties from the cache if necessary.</summary>
        Private Sub ResetProperties()
            Dim PropInfo As System.Reflection.PropertyInfo
            For Each HashVal As KeyValuePair(Of String, Object) In l_HashTable
                PropInfo = ObjectToDisplay.GetType.GetProperty(HashVal.Key)
                PropInfo.SetValue(ObjectToDisplay, HashVal.Value, Nothing)
            Next
        End Sub

        ''' <summary>Supporting Method: Updates the underlying datatables with the changes made in the various
        ''' controls.</summary>
        ''' <remarks>This is a manual update regardless of the databinding method selected as this avoids multiple updates
        ''' being triggered as each property is modified.</remarks>
        Private Sub UpdateData()
            Try
                'Maps the control data back to the appropriate datarow.
                For Each curControl In Me.DbiWSFObjectDetailMain.Controls
                    If curControl.Tag IsNot Nothing Then
                        Dim curCol As DataColumn = curControl.Tag.ActualDataColumn
                        Dim curVal As Object = GetValue(curControl)
                        If curVal IsNot Nothing Then
                            Try
                                Me.ObjectToDisplay.AttachedDataRow.Item(curCol) = curVal
                            Catch ex As Exception
                                'Issue with property, may not exist or be an automation issue.
                            End Try
                        End If
                    End If
                Next
                Me.WSFObject.WSFDatabinding.ManualUpdateDatabases()
            Catch ex As Exception
                Throw New Exception("Error Saving Form Data", ex) '<Generic Error>
            End Try

        End Sub

        ''' <summary>Supporting Method: Translates a specific control value to a typed object.</summary>
        Private Function GetValue(ByRef ControlToParse As Object) As Object
            Dim returnObject As Object
            Select Case ControlToParse.GetType.ToString
                Case GetType(Windows.Forms.TextBox).ToString
                    If ControlToParse.ReadOnly = True Then
                        returnObject = New System.Guid(ControlToParse.Text.ToString)
                    Else
                        returnObject = ControlToParse.Text
                    End If

                Case GetType(Windows.Forms.NumericUpDown).ToString
                    returnObject = CInt(ControlToParse.Value)
                Case GetType(dbiWSF.ControlLibrary.dbiDateTime).ToString
                    returnObject = ControlToParse.DateTimeValue
                Case GetType(Windows.Forms.MaskedTextBox).ToString
                    returnObject = CDec(ControlToParse.Text)
                Case GetType(Windows.Forms.ComboBox).ToString
                    returnObject = ControlToParse.SelectedValue
                Case GetType(dbiWSF.ControlLibrary.RecurrenceDaysOfWeek).ToString
                    returnObject = ControlToParse.DaysOfWeek
                Case Else
                    returnObject = Nothing
            End Select

            Return returnObject

        End Function

        ''' <summary>Supporting Method: Sets the form caption text for the ObjectToDisplay property.</summary>
        Private Sub SetText()
            Select Case Me.ObjectToDisplay.GetType.ToString
                Case GetType(dbiWSF.FrameworkObjects.objWarehouse).ToString
                    Me.Text = "Details for Warehouse: " + ObjectToDisplay.Description
                Case GetType(dbiWSF.FrameworkObjects.objLoadingDock).ToString
                    Me.Text = "Details for Warehouse: " + _
                            WSFObject.GetWarehouseFromGUID(ObjectToDisplay.WarehouseID).Description + _
                            " Loading Dock: " + ObjectToDisplay.Description
                Case GetType(dbiWSF.FrameworkObjects.objShipment).ToString
                    Me.Text = "Details for Shipment: " + ObjectToDisplay.Description
                Case GetType(dbiWSF.FrameworkObjects.objOrderHeader).ToString
                    Me.Text = "Details for Order Header: " + ObjectToDisplay.OrderEntryID.ToString
                Case GetType(dbiWSF.FrameworkObjects.objOrderDetail).ToString
                    Me.Text = "Details for Order Header: " + _
                            WSFObject.GetOrderHeaderFromGUID(ObjectToDisplay).OrderEntryID.ToString + _
                            " LineNumber: " + ObjectToDisplay.LineNumber.ToString
                Case GetType(dbiWSF.FrameworkObjects.objCargoType).ToString
                    Me.Text = "Details for Cargo Type: " + ObjectToDisplay.Description
                Case GetType(dbiWSF.FrameworkObjects.objLoadingDockException).ToString
                    Me.Text = "Details for Loading Dock Exception: " + ObjectToDisplay.Description
                Case GetType(dbiWSF.FrameworkObjects.objRecurrence).ToString
                    Me.Text = "Details for Recurrence: " + ObjectToDisplay.Description
            End Select
        End Sub
#End Region


    End Class
End Namespace
